/*****************************************************************************
// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.
*****************************************************************************/

// ************************************************************************* //
//                            avtWDataFileFormat.h                           //
// ************************************************************************* //

#ifndef AVT_WData_FILE_FORMAT_H
#define AVT_WData_FILE_FORMAT_H

#include <avtMTSDFileFormat.h>

#include <vector>
#include <complex>

typedef std::complex<float> Complex;

#include "wdata.h"

// ****************************************************************************
//  Class: WDataVariable
//
//  Purpose:
//
//  Programmer: gabrielw
//  Creation:   Wed Jul 29 19:18:00 PST 2020
//
//  Modifications:
//    Kathleen Biagas, Wed Sept 22, 2021
//    Have getVariable, isScalar and isVector return false to fix compile error
//    on Windows.  Cast numberOfVariables return to int. Remove unneeded ';'.
//
// ****************************************************************************

class WDataVariable
{
public:
    WDataVariable(wdata_metadata *wdmd, int varid, int precdowngrade);
    virtual ~WDataVariable() { ; }

    virtual bool getVariable(const char *_varname, int cycleid, float *data_for_visit) { return false; }

    int numberOfVariables() { return int(varname.size()); }
    std::string getIthVariableName(int ith) { return varname[ith]; }
    std::string getIthVariableUnit(int ith) { return varunit[ith]; }

    virtual bool isScalar() { return false; }
    virtual bool isVector() { return false; }

protected:
    int loadCycle(int cycleid);

    int vid;            // index of varaiable in md->vars table
    int d2f;            // downgrade double to float
    wdata_metadata *md; // variable info
    int loadedcycle;

    void *data; // each varaiable has data

    std::vector<std::string> varname; // list of var names that can be generated from this variable
    std::vector<std::string> varunit; // corresponding units
};

class WDataRealVariable : public WDataVariable
{
public:
    WDataRealVariable(wdata_metadata *wdmd, int varid, int precdowngrade);
    ~WDataRealVariable() { free(data); };

    bool getVariable(const char *_varname, int cycleid, float *data_for_visit);

    bool isScalar() { return true; };
    bool isVector() { return false; };

protected:
    float *dataR;
};

enum cplxtrans
{
    cabs,
    carg,
    cre,
    cim
};
class WDataComplexVariable : public WDataVariable
{
public:
    WDataComplexVariable(wdata_metadata *wdmd, int varid, int precdowngrade);
    ~WDataComplexVariable() { free(data); };

    bool getVariable(const char *_varname, int cycleid, float *data_for_visit);

    bool isScalar() { return true; };
    bool isVector() { return false; };

protected:
    Complex *dataC;
    std::vector<cplxtrans> trans; // transformations
};

class WDataVectorVariable : public WDataVariable
{
public:
    WDataVectorVariable(wdata_metadata *wdmd, int varid, int precdowngrade);
    ~WDataVectorVariable() { free(data); };

    bool getVariable(const char *_varname, int cycleid, float *data_for_visit);

    bool isScalar() { return false; };
    bool isVector() { return true; };

protected:
    float *dataVx;
    float *dataVy;
    float *dataVz;
};

// ****************************************************************************
//  Class: avtWDataFileFormat
//
//  Purpose:
//      Reads in WData files as a plugin to VisIt.
//
//  Programmer: gabrielw -- generated by xml2avt
//  Creation:   Wed Jul 29 19:18:00 PST 2020
//
// ****************************************************************************

class avtWDataFileFormat : public avtMTSDFileFormat
{
public:
    avtWDataFileFormat(const char *);
    virtual ~avtWDataFileFormat();

    //
    // This is used to return unconvention data -- ranging from material
    // information to information about block connectivity.
    //
    // virtual void      *GetAuxiliaryData(const char *var, int timestep,
    //                                     const char *type, void *args,
    //                                     DestructorFunction &);
    //

    //
    // If you know the times and cycle numbers, overload this function.
    // Otherwise, VisIt will make up some reasonable ones for you.
    //
    virtual void GetCycles(std::vector<int> &);
    virtual void GetTimes(std::vector<double> &);

    virtual int GetNTimesteps(void);

    virtual const char *GetType(void) { return "WData"; };
    virtual void FreeUpResources(void);

    virtual vtkDataSet *GetMesh(int, const char *);
    virtual vtkDataArray *GetVar(int, const char *);
    virtual vtkDataArray *GetVectorVar(int, const char *);

protected:
    // DATA MEMBERS

    wdata_metadata wdmd;

    virtual void PopulateDatabaseMetaData(avtDatabaseMetaData *, int);

    std::vector<WDataVariable *> variable;

    std::string dbcomment;
};

#endif
